Public Class Form1
    Sub ResetGame()
        Dim ctrl As Control
        For Each ctrl In Me.Controls
            If TypeOf (ctrl) Is Button And ctrl.Name <> "btnNewGame" Then
                ctrl.Text = String.Empty
            End If
        Next
        lblMessages.Text = ""
        CorrectEnabledState(True)
    End Sub
    Private Sub btnNewGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNewGame.Click
        ResetGame()
    End Sub
    Private Sub CorrectEnabledState(ByVal ButtonEnabledState As Boolean)
        Dim ctrl As Control
        For Each ctrl In Me.Controls
            If TypeOf (ctrl) Is Button And ctrl.Name <> "btnNewGame" Then
                ctrl.Enabled = ButtonEnabledState
            End If
        Next
    End Sub
    Private Sub CorrectEnabledState()
        Dim ctrl As Control
        For Each ctrl In Me.Controls
            If TypeOf (ctrl) Is Button And ctrl.Name <> "btnNewGame" Then
                If ctrl.Text = String.Empty Then
                    ctrl.Enabled = True
                Else
                    ctrl.Enabled = False
                End If
            End If
        Next
    End Sub
    Sub ComputerPlay()
        If ComputerPlayToWin() Then Exit Sub

        Dim RandomGenerator As New Random()
        Dim intRandom As Integer
        Dim intCount As Integer = 0
        Dim ctrl As Control
        intRandom = RandomGenerator.Next(20, 100)
        While intCount < intRandom
            For Each ctrl In Me.Controls
                If TypeOf (ctrl) Is Button And ctrl.Name <> "btnNewGame" Then
                    If ctrl.Text = String.Empty Then
                        intCount += 1
                        If intCount = intRandom Then
                            ctrl.Text = "O"
                            ctrl.Enabled = False
                            Exit For
                        End If
                    End If
                End If
            Next
        End While
    End Sub
    Private Sub TicTacToe_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn20.Click, btn10.Click, btn01.Click, btn21.Click, btn11.Click, btn02.Click, btn22.Click, btn12.Click, btn00.Click
        CorrectEnabledState(False)
        Application.DoEvents() 'Allows the screen to refresh
        CType(sender, Button).Text = "X"
        If IsGameOver() Then
            MsgBox("Game Over")
        Else
            lblMessages.Text = "Computer selecting ..."
            Application.DoEvents() 'Allows the screen to refresh
            ComputerPlay()
            If IsGameOver() Then
                MsgBox("Game Over")
            Else
                lblMessages.Text = "Select your next position ..."
                CorrectEnabledState()
            End If
        End If
    End Sub
    Sub Winner(ByVal strWinner As String)
        Dim strMessage As String
        If strWinner = "X" Then
            strMessage = "You win!!"
        ElseIf strWinner = "O" Then
            strMessage = "Computer wins!!"
        Else
            strMessage = strWinner
        End If
        lblMessages.Text = strMessage
    End Sub
    Function IsGameOver() As Boolean
        If btn00.Text = btn01.Text And btn01.Text = btn02.Text And btn02.Text <> String.Empty Then
            'Winner on top Row
            Call Winner(btn00.Text)
            Return True
        End If
        If btn10.Text = btn11.Text And btn11.Text = btn12.Text And btn12.Text <> String.Empty Then
            'Winner on middle Row
            Call Winner(btn10.Text)
            Return True
        End If
        If btn20.Text = btn21.Text And btn21.Text = btn22.Text And btn22.Text <> String.Empty Then
            'Winner on bottom Row
            Call Winner(btn20.Text)
            Return True
        End If

        If btn00.Text = btn10.Text And btn10.Text = btn20.Text And btn20.Text <> String.Empty Then
            'Winner on first column
            Call Winner(btn00.Text)
            Return True
        End If
        If btn01.Text = btn11.Text And btn11.Text = btn21.Text And btn21.Text <> String.Empty Then
            'Winner on second column
            Call Winner(btn01.Text)
            Return True
        End If
        If btn02.Text = btn12.Text And btn12.Text = btn22.Text And btn22.Text <> String.Empty Then
            'Winner on third column
            Call Winner(btn02.Text)
            Return True
        End If

        If btn00.Text = btn11.Text And btn11.Text = btn22.Text And btn22.Text <> String.Empty Then
            'Winner on diagonal top left to bottom right
            Call Winner(btn00.Text)
            Return True
        End If
        If btn20.Text = btn11.Text And btn11.Text = btn02.Text And btn02.Text <> String.Empty Then
            'Winner on diagonal bottom left to top right
            Call Winner(btn20.Text)
            Return True
        End If

        'Test for a tie, all square full
        Dim ctrl As Control
        Dim intOpenings As Integer = 0
        For Each ctrl In Me.Controls
            If TypeOf (ctrl) Is Button And ctrl.Name <> "btnNewGame" Then
                If ctrl.Text = String.Empty Then
                    intOpenings = intOpenings + 1
                End If
            End If
        Next
        If intOpenings = 0 Then
            Call Winner("It's a tie.")
            Return True
        End If

        Return False
    End Function
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        CorrectEnabledState(False)
        lblMessages.Text = "Click new game to begin."
    End Sub
    Private Function CheckForWin(ByRef btnFirst As Windows.Forms.Button, ByRef btnSecond As Windows.Forms.Button, ByRef btnThird As Windows.Forms.Button, ByVal stringToFind As String, ByVal strOpponentsMark As String) As Boolean
        Dim intSum As Int16 = 0S
        'Check to see if we can win on this row
        'We can we if we have two marks and no opponent marks on the row
        'If there is an opponents mark we are blocked so return false
        If btnFirst.Text = stringToFind Then
            intSum += 1S
        ElseIf btnFirst.Text = strOpponentsMark Then
            Return False
        End If

        If btnSecond.Text = stringToFind Then
            intSum += 1S
        ElseIf btnSecond.Text = strOpponentsMark Then
            Return False
        End If
        If btnThird.Text = stringToFind Then
            intSum += 1S
        ElseIf btnThird.Text = strOpponentsMark Then
            Return False
        End If

        'We will win on this turn
        'so just mark the entire row to save some resources
        If intSum = 2 Then
            btnFirst.Text = stringToFind
            btnSecond.Text = stringToFind
            btnThird.Text = stringToFind
            Return True
        Else
            Return False
        End If
    End Function
    Private Function ComputerPlayToWin() As Boolean
        If CheckForWin(btn00, btn01, btn02, "O", "X") Then
            'Winner on top Row
            Call Winner("0")
            Return True
        End If
        If CheckForWin(btn10, btn11, btn12, "O", "X") Then
            'Winner on middle Row
            Call Winner("O")
            Return True
        End If
        If CheckForWin(btn20, btn21, btn22, "O", "X") Then
            'Winner on third Row
            Call Winner("O")
            Return True
        End If
        If CheckForWin(btn00, btn10, btn20, "O", "X") Then
            'Winner on first column
            Call Winner("O")
            Return True
        End If
        If CheckForWin(btn01, btn11, btn21, "O", "X") Then
            'Winner on second column
            Call Winner("O")
            Return True
        End If
        If CheckForWin(btn02, btn12, btn22, "O", "X") Then
            'Winner on third column
            Call Winner("O")
            Return True
        End If

        If CheckForWin(btn00, btn11, btn22, "O", "X") Then
            'Winner on diagonal top left to bottom right
            Call Winner("O")
            Return True
        End If
        If CheckForWin(btn20, btn11, btn02, "O", "X") Then
            'Winner on diagonal bottom left to top right
            Call Winner("O")
            Return True
        End If
    End Function

End Class
